<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="第三十二章SpringMVCUnit1springmvc 1概述  1.1spring mvc简介  Spring MVC框架是有一个MVC框架，通过实现Model-View-Controller模式来很好地将数据、业务与展现进行分离。从这样一个角度来说，Spring MVC和Struts、Struts2非常类似。Spring MVC的设计是围绕DispatcherServlet展开的，Dispa">
<meta property="og:type" content="article">
<meta property="og:title" content="Hexo">
<meta property="og:url" content="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E4%B8%89%E5%8D%81%E4%BA%8C%E7%AB%A0SpringMVC/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="第三十二章SpringMVCUnit1springmvc 1概述  1.1spring mvc简介  Spring MVC框架是有一个MVC框架，通过实现Model-View-Controller模式来很好地将数据、业务与展现进行分离。从这样一个角度来说，Spring MVC和Struts、Struts2非常类似。Spring MVC的设计是围绕DispatcherServlet展开的，Dispa">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2021-12-19T17:38:00.248Z">
<meta property="article:modified_time" content="2021-12-19T17:38:00.254Z">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/notes-on-computer-expertise/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/notes-on-computer-expertise/favicon.png">
  
  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css">

  
  
<link rel="stylesheet" href="/notes-on-computer-expertise/css/style.css">

  
    
<link rel="stylesheet" href="/notes-on-computer-expertise/fancybox/jquery.fancybox.min.css">

  
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/notes-on-computer-expertise/" id="logo">Hexo</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/notes-on-computer-expertise/">Home</a>
        
          <a class="main-nav-link" href="/notes-on-computer-expertise/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/notes-on-computer-expertise/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://goofyer.gitee.io/notes-on-computer-expertise"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main"><article id="post-Java/第三十二章SpringMVC" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E4%B8%89%E5%8D%81%E4%BA%8C%E7%AB%A0SpringMVC/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:38:00.248Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第三十二章SpringMVC"><a href="#第三十二章SpringMVC" class="headerlink" title="第三十二章SpringMVC"></a>第三十二章SpringMVC</h2><h3 id="Unit1springmvc"><a href="#Unit1springmvc" class="headerlink" title="Unit1springmvc"></a>Unit1springmvc</h3><ul>
<li><p>1概述</p>
<ul>
<li><p>1.1spring mvc简介</p>
<ul>
<li>Spring MVC框架是有一个MVC框架，通过实现Model-View-Controller模式来很好地将数据、业务与展现进行分离。从这样一个角度来说，Spring MVC和Struts、Struts2非常类似。Spring MVC的设计是围绕DispatcherServlet展开的，DispatcherServlet负责将请求派发到特定的handler。通过可配置的handler mappings、view resolution、locale以及theme resolution来处理请求并且转到对应的视图。</li>
</ul>
</li>
<li><p>1.2springmvc的核心组件和执行流程</p>
<ul>
<li>DispatcherServlet，这个Servlet会接受所有的请求，是整个框架的控制中心，负责整体执行逻辑的控制,它会将具体的工作交由具体的其他组件来实现。</li>
<li>HandlerMapping，这个组件用来注册和查询url和处理器映射关系，即DispatcherServlet接受到了一个请求后，听过这个组件来决定使用哪个handler来处理。</li>
<li>HandlerAdapter，这个组件用来适配各种各样的handler形式，比如实现Controller接口形式的处理器，实现HttpRequestHandler接口形式的处理器，使用@RequestMapping注解的方法，甚至另外一个servlet。</li>
<li>Handler，就是我们实现的控制器。</li>
<li>ModelAndView，这个组件用来封装模型数据和视图。</li>
<li>ViewResolver，视图解析器，用来将一个视图名称解析成一个view对象</li>
<li>View 视图,其作用是将模型数据和视图模板渲染出来，并输出到response中。</li>
<li><p>一次HTTP请求的旅行:</p>
<ul>
<li>客户端发起HTTP请求到servlet容器，如tomcat，servlet容器将请求交到DispatchServlet去处理</li>
<li>DispatchServlet拿到请求后，解析出请求的url，然后找HandlerMapping去获取这个请求要处理的handler。</li>
<li>HandlerMapping返回HandlerExecutionChain，它会封装具体的handler和拦截器</li>
<li>DispatchServlet通过handler去找对应的HandlerAdapter</li>
<li>调用HandlerAdapter，其内部会调用具体的handler，执行具体的业务逻辑</li>
<li>HandlerAdapter获取具体的handler执行结果，返回ModelAndView</li>
<li>DispatchServlet获取HandlerAdapter返回的ModelAndView</li>
<li>DispatchServlet通过ModelAndView去找ViewResolver解析出一个真实的view对象（逻辑视图到实际视图）</li>
<li>DispatchServlet获取解析出来的View对象</li>
<li>DispatchServlet通过View去渲染response返回结果。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="子主题-2"><a href="#子主题-2" class="headerlink" title="子主题 2"></a>子主题 2</h3><h3 id="项目1-稻草问答"><a href="#项目1-稻草问答" class="headerlink" title="项目1 稻草问答"></a>项目1 稻草问答</h3><ul>
<li><p>1稻草问答项目搭建</p>
<ul>
<li><p>1.1稻草问答项目</p>
<ul>
<li><p>介绍:知识问答系统,目的是为了及时解决学员在线学习遇到的各类问题.此系统采用互联网架构。利用Redis缓存数据，利用ES提供查询性能，利用Kafka消除并发都赛，分布式微服务技术提升并发性能</p>
<ul>
<li><p>功能</p>
<ul>
<li>学员     登录      讲师</li>
<li>提问   回复</li>
<li>提问评论</li>
<li>相关提问</li>
<li>我的提问 任务</li>
<li>收藏</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>1.2项目部署结构</p>
</li>
<li>1.3原型</li>
<li><p>1.4项目搭建</p>
<ul>
<li><p>项目结构</p>
<ul>
<li><p>Straw-common</p>
<ul>
<li>通用参数</li>
</ul>
</li>
<li><p>Straw-config</p>
<ul>
<li>配置管理</li>
</ul>
</li>
<li><p>Straw-eureka-server</p>
<ul>
<li>注册服务</li>
</ul>
</li>
<li><p>Straw-gateway</p>
<ul>
<li>网关服务</li>
</ul>
</li>
<li><p>Straw-model</p>
<ul>
<li>实体模型</li>
</ul>
</li>
<li><p>Straw-portal</p>
<ul>
<li>门户入口</li>
</ul>
</li>
<li><p>Straw-search</p>
<ul>
<li>搜索</li>
</ul>
</li>
<li><p>Straw-search-api</p>
<ul>
<li>搜索API</li>
</ul>
</li>
</ul>
</li>
<li><p>1.4.1straw-portal搭建</p>
<ul>
<li><p>用spring web组件创建模块</p>
<ul>
<li><p>配置strawpom文件</p>
<ul>
<li>&lt;?xml version=”1.0” encoding=”UTF-8”?&gt;<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.tedu</groupId>
<artifactId>straw</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.tedu</groupId>
<artifactId>straw-portal</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>straw-portal</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
</project>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>1.5部署前段原型</p>
<ul>
<li>1.5.1下载网站原型</li>
<li><p>1.5.2部署项目</p>
<ul>
<li><p>配置strawportal pom文件</p>
<ul>
<li>&lt;?xml version=”1.0” encoding=”UTF-8”?&gt;<br><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><br><modelVersion>4.0.0</modelVersion><br><parent><br><groupId>cn.tedu</groupId><br><artifactId>straw</artifactId><br><version>0.0.1-SNAPSHOT</version><br><relativePath/> <!-- lookup parent from repository -->
</parent><br><groupId>cn.tedu</groupId><br><artifactId>straw-portal</artifactId><br><version>0.0.1-SNAPSHOT</version><br><name>straw-portal</name><br><description>Demo project for Spring Boot</description><properties>
<java.version>1.8</java.version>
</properties>

</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><dependencies><br>  <dependency></p>
<pre><code>  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
</code></pre><p>  &lt;/dependency&gt;<br>  <dependency></p>
<pre><code>  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
</code></pre><p>  &lt;/dependency&gt;<br>  <dependency></p>
<pre><code>  &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
  &lt;artifactId&gt;lombok&lt;/artifactId&gt;
</code></pre><p>  &lt;/dependency&gt;<br>&lt;/dependencies&gt;<br>&lt;/project&gt;</p>
<ul>
<li>1.5.3启动springboot测试</li>
</ul>
</li>
</ul>
</li>
<li><p>2稻草问答业务功能分析</p>
<ul>
<li><p>2.1软件分析和设计思路</p>
<ul>
<li><p>分析软件功能，搞清楚业务流转过程</p>
<ul>
<li><p>找出软件中的业务实体，根据实体设计类和数据表，找到数据结构</p>
<ul>
<li>根据业务流程设计软件功能明便携软件代码，编写计算方法</li>
</ul>
</li>
<li><p>2.2概要分析</p>
<ul>
<li>用户管理模块：登录，注册，权限管理</li>
<li>用户问答模块：提问，回答问题，讨论，收藏</li>
<li>后台管理模块：用户管理，系统维护</li>
</ul>
</li>
<li><p>2.3数据结构设计</p>
<ul>
<li><p>Answer</p>
<ul>
<li>| id             | int         | NO   | PRI | NULL    | auto_increment |</li>
<li>| content        | longtext    | NO   |     | NULL    |                |</li>
<li>| user_id        | int         | NO   |     | NULL    |                |</li>
<li>| user_nick_name | varchar(20) | NO   |     | NULL    |                |</li>
<li>| question_id    | int         | NO   |     | NULL    |                |</li>
<li>| is_accepted    | int         | NO   |     | NULL    |                |</li>
<li>| gmt_create     | datetime    | YES  |     | NULL    |                |</li>
<li>| gmt_modified   | datetime    | YES  |     | NULL    |                |</li>
</ul>
</li>
<li><p>class_info</p>
<ul>
<li>| id           | int          | NO   | PRI | NULL    | auto_increment |</li>
<li>| name         | varchar(30)  | NO   |     | NULL    |                |</li>
<li>| invite_code  | varchar(255) | NO   |     | NULL    |                |</li>
<li>| is_enabled   | tinyint      | NO   |     | NULL    |                |</li>
<li>| gmt_create   | datetime     | YES  |     | NULL    |                |</li>
<li>| gmt_modified | datetime     | YES  |     | NULL    |                |</li>
</ul>
</li>
<li><p>user</p>
<ul>
<li>| id           | int         | NO   | PRI | NULL    | auto_increment |</li>
<li>| username     | varchar(20) | YES  | UNI | NULL    |                |</li>
<li>| nick_name    | varchar(20) | YES  |     | NULL    |                |</li>
<li>| password     | char(68)    | NO   |     | NULL    |                |</li>
<li>| gender       | int         | YES  |     | NULL    |                |</li>
<li>| day_of_birth | date        | YES  |     | NULL    |                |</li>
<li>| phone        | varchar(20) | YES  | UNI | NULL    |                |</li>
<li>| class_id     | int         | YES  |     | NULL    |                |</li>
<li>| is_enabled   | int         | YES  |     | NULL    |                |</li>
<li>| is_locked    | int         | YES  |     | NULL    |                |</li>
<li>| account_type | int         | YES  |     | NULL    |                |</li>
<li>| gmt_create   | datetime    | YES  |     | NULL    |                |</li>
<li>| gmt_modified | datetime    | YES  |     | NULL    |                |</li>
</ul>
</li>
<li><p>comment</p>
<ul>
<li>| id             | int         | NO   | PRI | NULL    | auto_increment |</li>
<li>| user_id        | int         | NO   |     | NULL    |                |</li>
<li>| user_nick_name | varchar(20) | NO   |     | NULL    |                |</li>
<li>| answer_id      | int         | NO   |     | NULL    |                |</li>
<li>| content        | text        | NO   |     | NULL    |                |</li>
<li>| gmt_create     | datetime    | YES  |     | NULL    |                |</li>
<li>| gmt_modified   | datetime    | YES  |     | NULL    |                |</li>
</ul>
</li>
<li><p>permission</p>
<ul>
<li>| id           | int          | NO   | PRI | NULL    | auto_increment |</li>
<li>| authority    | varchar(255) | NO   |     | NULL    |                |</li>
<li>| description  | varchar(255) | YES  |     | NULL    |                |</li>
<li>| gmt_create   | datetime     | YES  |     | NULL    |                |</li>
<li>| gmt_modified | datetime     | YES  |     | NULL    |                |</li>
</ul>
</li>
<li><p>question</p>
<ul>
<li>| id             | int          | NO   | PRI | NULL    | auto_increment |</li>
<li>| title          | varchar(100) | NO   |     | NULL    |                |</li>
<li>| content        | longtext     | NO   |     | NULL    |                |</li>
<li>| user_id        | int          | NO   |     | NULL    |                |</li>
<li>| user_nick_name | varchar(20)  | NO   |     | NULL    |                |</li>
<li>| status         | int          | NO   |     | NULL    |                |</li>
<li>| hits           | int          | NO   |     | NULL    |                |</li>
<li>| tag_ids        | varchar(255) | YES  |     | NULL    |                |</li>
<li>| gmt_create     | datetime     | YES  |     | NULL    |                |</li>
<li>| gmt_modified   | datetime     | YES  |     | NULL    |                |</li>
</ul>
</li>
<li><p>question_tag</p>
<ul>
<li>| id           | int      | NO   | PRI | NULL    | auto_increment |</li>
<li>| tag_id       | int      | NO   |     | NULL    |                |</li>
<li>| question_id  | int      | NO   |     | NULL    |                |</li>
<li>| gmt_create   | datetime | YES  |     | NULL    |                |</li>
<li>| gmt_modified | datetime | YES  |     | NULL    |                |</li>
</ul>
</li>
<li><p>role</p>
<ul>
<li>| id           | int          | NO   | PRI | NULL    | auto_increment |</li>
<li>| name         | varchar(255) | NO   |     | NULL    |                |</li>
<li>| gmt_create   | datetime     | YES  |     | NULL    |                |</li>
<li>| gmt_modified | datetime     | YES  |     | NULL    |                |</li>
</ul>
</li>
<li><p>role_permission</p>
<ul>
<li>| id            | int      | NO   | PRI | NULL    | auto_increment |</li>
<li>| role_id       | int      | NO   |     | NULL    |                |</li>
<li>| permission_id | int      | NO   |     | NULL    |                |</li>
<li>| gmt_create    | datetime | YES  |     | NULL    |                |</li>
<li>| gmt_modified  | datetime | YES  |     | NULL    |                |</li>
</ul>
</li>
<li><p>tag</p>
<ul>
<li>| id           | int          | NO   | PRI | NULL    | auto_increment |</li>
<li>| name         | varchar(255) | NO   |     | NULL    |                |</li>
<li>| created_user | varchar(255) | NO   |     | NULL    |                |</li>
<li>| gmt_create   | datetime     | YES  |     | NULL    |                |</li>
<li>| gmt_modified | datetime     | YES  |     | NULL    |                |</li>
</ul>
</li>
<li><p>user_question</p>
</li>
<li>user_role</li>
</ul>
</li>
<li><p>2.4初始化数据库</p>
<ul>
<li>创建数据表</li>
<li>插入数据</li>
</ul>
</li>
</ul>
</li>
<li><p>3用lombok简化开发</p>
<ul>
<li><p>3.1Lombok介绍：</p>
<ul>
<li>Lombok项目是一个Java库，它会自动插入编辑器和构建工具中，Lombok提供了一组有用的注释，用来消除Java类中的大量样板代码。仅五个字符(@Data)就可以替换数百行代码从而产生干净，简洁且易于维护的Java类。</li>
</ul>
</li>
<li><p>3.2Lombok安装</p>
<ul>
<li>File-》settings》lombok插件</li>
</ul>
</li>
<li><p>3.3Lombok库依赖</p>
<ul>
<li><dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</li>
</ul>
</li>
<li><p>3.4Lombok常用注解</p>
<ul>
<li>@Setter ：注解在类或字段，注解在类时为所有字段生成setter方法，注解在字段上时只为该字段生成setter方法。</li>
<li>@Getter ：使用方法同上，区别在于生成的是getter方法。</li>
<li>@ToString ：注解在类，添加toString方法。</li>
<li>@EqualsAndHashCode： 注解在类，生成hashCode和equals方法。</li>
<li>@NoArgsConstructor： 注解在类，生成无参的构造方法。</li>
<li>@RequiredArgsConstructor： 注解在类，为类中需要特殊处理的字段生成构造方法，比如final和被@NonNull注解的字段。</li>
<li>@AllArgsConstructor： 注解在类，生成包含类中所有字段的构造方法。</li>
<li>@Data： 注解在类，生成setter/getter、equals、canEqual、hashCode、toString方法，如为final属性，则不会为该属性生成setter方法。</li>
<li>@Slf4j： 注解在类，生成log变量，严格意义来说是常量</li>
</ul>
</li>
<li><p>3.5测试</p>
<ul>
<li><p>3.5.1创建一个msg类型</p>
<ul>
<li>@Data<br>public class Msg {<br>private int id;<br>private String name;<br>private String text;<br>}</li>
</ul>
</li>
<li><p>3.5.2编写测试案例，测试是否生成方法</p>
<ul>
<li>public class TestCase {<br>@Test<br>public void testMsg()<br>{<br>Msg msg=new Msg();<br>msg.setId(1);<br>msg.setName(“234”);<br>msg.setText(“hello”);<br>System.out.println(msg);<br>}</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>}</p>
<pre><code>        - 3.6slf4j

            - 3.6.1创建一个loggerDemo类型

                - @Slf4j
</code></pre><p>public class LoggerDemo {<br>    public  LoggerDemo()<br>    {<br>        log.debug(“hello world!”);<br>    }<br>}</p>
<pre><code>            - 3.6.2编写测试案例，测试是否生成方法

                - @Test
</code></pre><p>public void testLogger() {<br>    LoggerDemo demo = new LoggerDemo();<br>}</p>
<pre><code>        - 3.7MyBatis Plus简化MyBatis

            - 3.7.1概述

                - MyBatis-Plus (opens new window)（简称 MP）是一个 MyBatis (opens new window)的增强工具，在 MyBatis 的基础上只做增强不做改变，为简化开发、提高效率而生。

            - 3.7.2依赖版本

                - 父

                    - &lt;dependencyManagement&gt;
&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;com.baomidou&lt;/groupId&gt;
        &lt;artifactId&gt;mybatis-plus-boot-starter&lt;/artifactId&gt;
        &lt;version&gt;3.3.1&lt;/version&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;
</code></pre><p>&lt;/dependencyManagement&gt;</p>
<pre><code>                - 子

                    - &lt;dependency&gt;
&lt;groupId&gt;com.baomidou&lt;/groupId&gt;
&lt;artifactId&gt;mybatis-plus-boot-starter&lt;/artifactId&gt;
</code></pre><p>&lt;/dependency&gt;</p>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<pre><code>            - 3.7.3 代码

                - 1.声明实体类User

                    - @Data
</code></pre><p>public class User {<br>    private Integer id;<br>    private String username;<br>    private String nick_name;<br>    private String password;<br>    private String gender;<br>    private LocalDate day_of_birth;<br>    private String phone;<br>    private Integer class_id;<br>    private Boolean is_enabled;<br>    private Boolean account_type;<br>    private LocalDate gmt_create;<br>    private LocalDate gmt_modified;<br>}</p>
<pre><code>                - 2.定义数据访问接口

                    - @Repository
</code></pre><p>public interface UserMapper extends BaseMapper<User> {</p>
<p>}</p>
<pre><code>                - 3.在启动类开启MaPPer接口扫描功能

                    - @MapperScan(&quot;cn.tedu.straw.portal.mapper&quot;)

                - 4.配置application.properties增加数据库参数，以及MyBAtisMapper日志

                    - spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
</code></pre><p>spring.datasource.url=jdbc:mysql://localhost:3306/straw?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&amp;serverTimezone = GMT&amp;allowPublicKeyRetrieval=true&amp;nullCatalogMeansCurrent=true<br>spring.datasource.username=root<br>spring.datasource.password=123456</p>
<pre><code>            - 3.7.4 测试（MapperTest）

                - @Test
</code></pre><p>public void testUserMapper() {<br>    User user = userMapper.selectById(1);<br>    System.out.println(user);<br>}</p>
<pre><code>        - 3.8代码生成器

            - 3.8.1依赖文件

                - &lt;dependency&gt;
&lt;groupId&gt;com.baomidou&lt;/groupId&gt;
&lt;artifactId&gt;mybatis-plus-extension&lt;/artifactId&gt;
&lt;version&gt;3.3.1&lt;/version&gt;
</code></pre><p>&lt;/dependency&gt;</p>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.1</version>
</dependency>

<pre><code>            - 3.8.2编写usercontroller

                - @RestController
</code></pre><p>@RequestMapping(“/portal/user”)<br>public class UserController {<br>    @Autowired<br>    IUserService userService;<br>    //<a target="_blank" rel="noopener" href="http://localhost:8080/portal/user/get?id=1">http://localhost:8080/portal/user/get?id=1</a><br>    @GetMapping(“/get”)<br>    /<em><br>    如果登录用户有、user/get权限 才能执行
     </em>/<br>    public User get(int id)<br>    {<br>        User user=userService.getById(id);<br>        return user;<br>    }<br>}</p>
<pre><code>    - 4spring安全框架

        - 4.1什么是spring安全框架

            - Spring Security 是一个能够为基于 Spring 的企业应用系统提供声明式的安全访问控制解决方案的安全框架；它提供了一组可以在 Spring 应用上下文中配置的 Bean，充分利用了 Spring IoC， DI 和 AOP 功能，为应用系统提供声明式的安全访问控制功能，减少了为企业系统安全控制编写大量重复代码的工作。

        - 4.2 spring安全框架的依赖

            - 子

                - &lt;dependency&gt;
&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
&lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
&lt;version&gt;1.3.0.RELEASE&lt;/version&gt;
</code></pre><p>&lt;/dependency&gt;</p>
<pre><code>            - 配置文件

                - spring.security.user.name=admin
                - spring.security.user.password=123456

        - 4.3密码加密

            - 单向散列算法Bcrypt

                - 代码

                    - //创建一个类作为配置文件，添加@Configration注解，使用@Bean注解配置
</code></pre><p>@Configuration<br>@EnableGlobalMethodSecurity(prePostEnabled = true)//开启权限注解<br>public class SecurityConfig extends WebSecurityConfigurerAdapter {<br>    //@Bean<br>    //public PasswordEncoder passwordEncoder()<br>    //{<br>    //    return new BCryptPasswordEncoder();<br>    //}<br>    //@Autowired<br>    //UserDetailsServiceImpl userDetailsService;</p>
<pre><code>@Override
protected void configure(AuthenticationManagerBuilder auth)throws Exception
&#123;
    super.configure(auth);
    /*
    添加一个测试用户 tom 密码123456 权限/user/get

    auth.inMemoryAuthentication().withUser(&quot;Tom&quot;)
        .password(&quot;&#123;bcrypt&#125;$2a$10$4WxQNiXb/gIcWc/8XiRqXOpR.0NoXlJnkTgI7FaM8rzm6ExH7C622&quot;)
        .authorities(&quot;/user/get&quot;,&quot;/user/list&quot;);
    auth.userDetailsService(userDetailsService);*/
&#125;

@Override
protected void configure(HttpSecurity http) throws Exception
&#123;
    http.csrf().disable().authorizeRequests()
        .antMatchers(
                &quot;/login.html&quot;,
                &quot;/register.html&quot;,
                &quot;/register&quot;,
                &quot;/js/*&quot;,
                &quot;/img/*&quot;,
                &quot;/css/*&quot;,
                &quot;/browser_components/**&quot;
        ).permitAll()
        .anyRequest().authenticated()
        .and().formLogin()
        .loginPage(&quot;/login.html&quot;)
        .loginProcessingUrl(&quot;/login&quot;)
        .failureUrl(&quot;/login.html?error&quot;)
        .defaultSuccessUrl(&quot;/index.html&quot;)
        .and().logout()
        .logoutUrl(&quot;/logout&quot;)
        .logoutSuccessUrl(&quot;/login.html?logout&quot;);
&#125;
</code></pre><p>}</p>
<pre><code>        - 4.4使用权限控制资源

            - 用途

                - 添加测试用户信息，并为用户分配权限

            - 代码

                - @Configuration
</code></pre><p>@EnableGlobalMethodSecurity(prePostEnabled = true)//开启权限注解<br>public class SecurityConfig extends WebSecurityConfigurerAdapter {<br>@Override<br>protected void configure(AuthenticationManagerBuilder auth)throws Exception<br>{<br>    //super.configure(auth);<br>    //添加一个测试用户 tom 密码123456 权限/user/get<br>    auth.inMemoryAuthentication().withUser(“Tom”)<br>        .password(“{bcrypt}$2a$10$4WxQNiXb/gIcWc/8XiRqXOpR.0NoXlJnkTgI7FaM8rzm6ExH7C622”)<br>        .authorities(“/user/get”,”/user/list”);<br>    //auth.userDetailsService(userDetailsService);*/<br>}</p>
<pre><code>        - 4.5利用数据库登录

            - 业务流程

                - 用户
                - userDetailServiceImpl
                - userServiceImpl
                - UserMapper
                - 数据库

            - 第一步 编写sql语句

                - select u.username,r.name,p.authority &quot; +
    &quot;from user u &quot; +
    &quot;left join user_role ur on u.id = ur.user_id &quot; +
    &quot;left join role r on r.id = ur.role_id &quot; +
    &quot;left join role_permission rp on r.id = rp.role_id &quot; +
    &quot;left join permission p on p.id = rp.permission_id &quot; +
    &quot;where u.id=#&#123;userId&#125;&quot;

            - 第二步 编写代码

                - @Override
</code></pre><p>protected void configure(AuthenticationManagerBuilder auth)throws Exception<br>{<br>    auth.userDetailsService(userDetailsService);<br>}</p>
<pre><code>                - 测试

                    - @Test
</code></pre><p>public void findUserByUsername()<br>{<br>    User user=userMapper.findUserByUsername(“admin”);<br>    System.out.println(user);<br>}</p>
<p>@Test<br>public void findUserPermissionById()<br>{<br>    List<Permission> list=userMapper.findUserPermissionById(1);<br>    for(Permission p:list)<br>    {<br>        System.out.println(p);<br>    }<br>}</p>
<pre><code>            - 在IUserService接口中声明功能方法，获取用户详细信息

                - public interface IUserService extends IService&lt;User&gt; &#123;
UserDetails getUserDetails(String username);
</code></pre><p>}</p>
<pre><code>            - 实现该方法

                - public class UserServiceImpl extends ServiceImpl&lt;UserMapper, User&gt; implements IUserService &#123;
@Autowired
UserMapper userMapper;
@Override
public UserDetails getUserDetails(String username) &#123;
    System.out.println(username);
    User user = userMapper.findUserByUsername(username);
    System.out.println(user);
    if (user == null)
        return null;
    List&lt;Permission&gt; permissions = userMapper.findUserPermissionById(user.getId());
    String[] arr = new String[permissions.size()];
    /*int i = 0;
    for (Permission p : permissions) &#123;
        arr[i++] = p.getAuthority();
        System.out.println(p);
    &#125;
    List&lt;Role&gt; roles = userMapper.findUserRolesById(user.getId());
    arr = Arrays.copyOf(arr, arr.length + roles.size());
    for (Role role : roles)
        arr[i++] = role.getName();*/
    UserDetails u = org.springframework.security.core.userdetails.User.builder()
                                                                      .username(user.getUsername())
                                                                      .password(user.getPassword())
                                                                      .authorities(arr)
                                                                      .build();
    System.out.println(u);

    return u;
&#125;
</code></pre><p>}</p>
<pre><code>                - 测试

                    - @Autowired
IUserService userService;
@Test
private void getUserDetails()
&#123;
    UserDetails user=userService.getUserDetails(&quot;admin&quot;);
    System.out.println(user);
&#125;
</code></pre><p>}</p>
<pre><code>        - 4.6控制授权范围

            - @Override
</code></pre><p>protected void configure(HttpSecurity http) throws Exception<br>{<br>    http.csrf().disable().authorizeRequests()<br>        .antMatchers(<br>                “/login.html”,<br>                “/register.html”,<br>                “/register”,<br>                “/js/<em>“,<br>                “/img/</em>“,<br>                “/css/<em>“,<br>                “/browser_components/*</em>“<br>        ).permitAll()<br>        .anyRequest().authenticated()<br>        .and().formLogin()<br>        .loginPage(“/login.html”)<br>        .loginProcessingUrl(“/login”)<br>        .failureUrl(“/login.html?error”)<br>        .defaultSuccessUrl(“/index.html”)<br>        .and().logout()<br>        .logoutUrl(“/logout”)<br>        .logoutSuccessUrl(“/login.html?logout”);</p>
<p>}</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E4%B8%89%E5%8D%81%E4%BA%8C%E7%AB%A0SpringMVC/" data-id="cl403sxr10017f8vu5q796nul" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E4%B8%89%E5%8D%81%E4%B8%89%E7%AB%A0Oracle/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          (no title)
        
      </div>
    </a>
  
  
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E4%B8%89%E5%8D%81%E4%B8%80%E7%AB%A0Spring/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title"></div>
    </a>
  
</nav>

  
</article>


</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Categories</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/C-%E5%B7%A5%E5%85%B7/">C#工具</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/C-%E5%B7%A5%E5%85%B7/">C++工具</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/Mysql/">Mysql</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/blender/">blender</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/linux/">linux</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/manim/">manim</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/spring/">spring</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/vba%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/">vba基础操作</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E5%88%9B%E9%80%A0%E6%A8%A1%E5%BC%8F/">创造模式</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/">操作系统</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/">操作系统基础知识</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%BC%80%E5%8F%91/">操作系统开发</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E5%AD%A6/">数学</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/">数据结构</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/">数据结构基础知识</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%A8%A1%E6%9D%BF/">模板</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/">深度学习</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%8B%B1%E8%AF%AD/">英语</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%99%9A%E5%B9%BB4/">虚幻4</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/">计算机组成原理</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/">计算机网络</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/notes-on-computer-expertise/tags/C/" rel="tag">C++</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/notes-on-computer-expertise/tags/C/" style="font-size: 10px;">C++</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/05/">May 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/03/">March 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/02/">February 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/01/">January 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2021/12/">December 2021</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/31/vue/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6%E9%AA%8C%E8%AF%81%E7%A0%81%E6%97%A0%E6%B3%95%E6%98%BE%E7%A4%BA/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/26/%E6%95%B0%E6%8D%AE%E5%BA%93/navicat%E5%AE%89%E8%A3%85/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/25/%E8%99%9A%E5%B9%BB4%E5%BC%95%E6%93%8E%E5%BC%80%E5%8F%91/%E8%99%9A%E5%B9%BB%E5%9B%9B%20mod%E5%88%B6%E4%BD%9C/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/23/python/python%E6%89%B9%E9%87%8F%E7%94%9F%E6%88%90%E6%95%B0%E6%8D%AE/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/23/vba%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C%E7%AC%94%E8%AE%B0/EXCEL%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/">(no title)</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2022 John Doe<br>
      Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/notes-on-computer-expertise/" class="mobile-nav-link">Home</a>
  
    <a href="/notes-on-computer-expertise/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/notes-on-computer-expertise/js/jquery-3.4.1.min.js"></script>



  
<script src="/notes-on-computer-expertise/fancybox/jquery.fancybox.min.js"></script>




<script src="/notes-on-computer-expertise/js/script.js"></script>





  </div>
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
        tex2jax: {
            inlineMath: [ ["$","$"], ["\\(","\\)"] ],
            skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
            processEscapes: true
        }
    });
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax();
        for (var i = 0; i < all.length; ++i)
            all[i].SourceElement().parentNode.className += ' has-jax';
    });
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML"></script>
</body>
</html>